Example 4-2 : User-Level DMA Access to VME
/* || This function assumes that any device programming needed to || prepare the device for input has been done (using PIO) before || the function is called. The bus number and device address || are function parameters. */ #define BLOCK_SIZE_TO_USE 4096 #include <udmalib.h> #include <sys/vmereg.h> extern void processOneBuffer(void *pBuffer); int readBlocks(int iBusNum, __uint32_t uiDevAddress) { udmaid_t *hEngine; /* handle returned by dma_open */ void *pDMAbuffer; /* pointer from dma_allocbuf */ vmeparms_t sParms; /* operation parms for dma_mkparms */ udmaprm_t *hParms; /* handle returned by dma_mkparms */ int iStartCode; /* return code of dma_start */ /* || Open the DMA engine. Terminate if it won't open. */ hEngine = dma_open(DMA_VMEBUS, iBusNum); if (!hEngine) { perror("dma_open"); return(-1); } /* || Allocate a special buffer for I/O. If that fails, || release the engine and terminate. */ hDMAbuffer = dma_allocbuf(hEngine, BLOCK_SIZE_TO_USE); if (!hDMAbuffer) { perror("dma_allocbuf"); dma_close(hEngine); return(-2); } /* || Set up the VME parameters and "make" them. A different set || of parameters is needed for each combination of vmeparms_t || values, buffer, and size. This example uses only one set. */ sParms.vp_block = 0; /* this device does not do blocks */ sParms.vp_datumsz = VME_DS_WORD; /* this is a 32-bit device */ sParms.vp_dir = VME_READ; /* input operation */ sParms.vp_throt = VME_THROT_256; /* smaller burst size */ sParms.vp_release = VME_REL_ROR; /* release on request */ sParms.vp_addrmod = VME_A32NPAMOD; /* address modifier */ hParms = dma_mkparms(hEngine, &sParms, pDMAbuffer, BLOCK_SIZE_TO_USE); if (!hParms) { perror("dma_mkparms"); dma_freebuf(pDMAbuffer); dma_close(hEngine); return(-3); } /* || Read and process blocks until error. */ for(iStartCode=0;iStartCode==0;) { iStartCode = dms_start(hEngine, uiDevAddress, hParms); if (!iStartCode) processOneBuffer(pDMAbuffer); } /* || Clean up and exit. */ dma_freeparms(hEngine, hParms); dma_freebuf(pDMAbuffer); dma_close(hEngine); return 0; }